package global

import (
	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"
	"go.uber.org/zap"
	"path"
)

var ServiceConfig *Config

type Config struct {
	Name      string         `mapstructure:"name"`
	Host      string         `mapstructure:"host"`
	Port      int            `mapstructure:"port"`
	Tags      []string       `mapstructure:"tags"`
	Consul    ConsulConfig   `mapstructure:"consul"`
	Chain     ChainConfig    `mapstructure:"chain"`
	MySql     MySqlConfig    `mapstructure:"mysql"`
	JWTConfig JWTConfig      `mapstructure:"jwt"`
	TokenName string         `mapstructure:"tokenname"`
	RabbitMQ  RabbitMQConfig `mapstructure:"rabbitmq"`
	TxQueue   QueueConfig    `mapstructure:"txqueue"`
}

type ConsulConfig struct {
	Host string `mapstructure:"host"`
	Port int    `mapstructure:"port"`
}

type ChainConfig struct {
	Deployer      string `mapstructure:"deployer"`
	PortalProver  string `mapstructure:"portal_prover"`
	TradeProver   string `mapstructure:"trade_prover"`
	TradeAuditor  string `mapstructure:"trade_auditor"`
	PortalManager string `mapstructure:"portal_manager"`
	TrustManager  string `mapstructure:"trust_manager"`
	TradeManager  string `mapstructure:"trade_manager"`
}

type MySqlConfig struct {
	Username string `mapstructure:"username"`
	Password string `mapstructure:"password"`
	Address  string `mapstructure:"address"`
	Port     int    `mapstructure:"port"`
	Database string `mapstructure:"database"`
}

type JWTConfig struct {
	SigningKey string `mapstructure:"signing_key"`
}

type RabbitMQConfig struct {
	Username string `mapstructure:"username"`
	Password string `mapstructure:"password"`
	Host     string `mapstructure:"host"`
	Port     int    `mapstructure:"port"`
}

type QueueConfig struct {
	Queue      string `mapstructure:"queue"`
	Exchange   string `mapstructure:"exchange"`
	BindingKey string `mapstructure:"bindingKey"`
}

func InitConfig(mode string) {
	// 初始化配置文件
	v := viper.New()
	v.SetConfigFile(path.Join("etc", "portal", "portal-"+mode+".yaml"))
	if err := v.ReadInConfig(); err != nil {
		Logger.Error("读取配置失败", err)
		return
	}
	ServiceConfig = new(Config)
	if err := v.Unmarshal(ServiceConfig); err != nil {
		Logger.Error("解析配置失败", err)
		return
	}
	zap.L().Info("server config", zap.Any("config", *ServiceConfig))
	v.WatchConfig()
	v.OnConfigChange(func(in fsnotify.Event) {
		Logger.Debug("配置文件修改了...", nil)
		if err := v.Unmarshal(ServiceConfig); err != nil {
			Logger.Error(err)
			return
		}
		Logger.Debug("server config:", map[string]any{"config": ServiceConfig})
	})
}
